package cn.maihe.elg.operation.service;

import cn.maihe.elg.operation.config.ElgConfig;
import cn.maihe.elg.operation.model.enums.UserType;
import cn.maihe.elg.operation.security.model.UserContext;
import cn.maihe.elg.operation.utils.UserContextUtil;
import cn.maihe.framework.starter.base.sql.BaseEntity;
import cn.maihe.framework.starter.base.sql.PageBo;
import cn.maihe.framework.starter.mybatis.dao.MybatisDaoImpl;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.google.common.collect.Maps;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

/**
 * @Description
 * @Author WJH
 * @Date 2021/03/25
 */
public abstract class BaseDaoService<T extends BaseEntity> {

    private Class<T> tClass;
    @Resource
    private ElgConfig elgConfig;
    public BaseDaoService() {
        this.tClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    /**
     * 当前登录用户
     */
    public UserContext getCurUserContext() {
        return UserContextUtil.getUserContext();
    }


    /**
     * 转化Map并附加curOrgCode、curUserType、curUserId
     */
    public <V> Map<String, Object> toMapAndAddParams(V vo) {
        UserContext userContext = getCurUserContext();
        Map reMap;
        if (vo instanceof Map) {
            reMap = (Map) vo;
        } else {
            reMap = beanToMap(vo);
        }
//        if(elgConfig!=null && elgConfig.getEnableCenterId()!=null){
//            reMap.put("enableCenterId", elgConfig.getEnableCenterId());
//        }
        if (userContext != null) {
            reMap.put("curOrgCode", "-1".equals(userContext.getOrgCode()) ? null : userContext.getOrgCode());
            reMap.put("curOrgId", userContext.getOrgId());
            reMap.put("curUserType", userContext.getUserType());
            reMap.put("curUserId", Long.valueOf(userContext.getId()));
            reMap.put("curUserName", userContext.getUsername());
            reMap.put("curBidderId", userContext.getBidderId());
            if (userContext.getUserType() == UserType.ACCOUNT.getType()) {
                reMap.put("centerIds", userContext.getCenterIds());
                reMap.put("institutionIds", userContext.getInstitutionIds());
            }
        }
        return reMap;
    }

    protected <T> Map<String, Object> beanToMap(T t) {
        Map reMap = Maps.newHashMap();
        if (t != null) {
            BeanMap.create(t).forEach((k, v) -> {
                reMap.put(k, v);
            });
        }
        return reMap;
    }

    public boolean exists(Wrapper<T> wrapper) {
        return MybatisDaoImpl.run().selectCount(wrapper) > 0;
    }

    /**
     * 新增
     */
    public Integer insert(T t) {
        return MybatisDaoImpl.run().insert(t);
    }


    /**
     * 批量新增
     */
    public boolean insert(List<T> list, int batchSize) {
        return MybatisDaoImpl.run().insertBatch(list, batchSize);
    }

    public Integer delete(Wrapper<T> wrapper) {
        return MybatisDaoImpl.run().delete(wrapper);
    }

    public Integer deleteById(Serializable id) {
        return MybatisDaoImpl.run().deleteById(this.tClass, id);
    }

    public Integer update(T entity, Wrapper<T> wrapper) {
        return MybatisDaoImpl.run().update(entity, wrapper);
    }

    public Integer updateById(T entity) {
        return MybatisDaoImpl.run().updateById(entity);
    }

    public T selectById(Serializable id) {
        return MybatisDaoImpl.run().selectById(this.tClass, id);
    }

    public PageBo<T> selectPageBo(Wrapper<T> wrapper, int page, int pageSize) {
        return MybatisDaoImpl.run().selectPageBo(wrapper, page, pageSize);
    }

    public List<T> selectList(Wrapper<T> wrapper) {
        return MybatisDaoImpl.run().selectList(wrapper);
    }

    public T selectOne(Wrapper<T> wrapper) {
        return MybatisDaoImpl.run().selectOne(wrapper);
    }

    public <E> List<E> selectListBySql(String statementId, Map<String, Object> parameterMap) {
        return MybatisDaoImpl.sql(this.tClass).selectListBySql(statementId, parameterMap);
    }

    public <E> E selectOneBySql(String statementId, Map<String, Object> parameterMap) {
        List<E> list = MybatisDaoImpl.sql(this.tClass).selectListBySql(statementId, parameterMap);
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    public <E> PageBo<E> selectPageBySql(String statementId, String statementCountId, Map<String, Object> parameterMap, int page, int pageSize) {
        return MybatisDaoImpl.sql(this.tClass).selectPageBySql(statementId, statementCountId, parameterMap, page, pageSize);
    }


    public Integer selectCountBySql(String statementCountId, Map<String, Object> parameterMap) {
        return MybatisDaoImpl.sql(this.tClass).selectCountBySql(statementCountId, parameterMap);
    }

    public Integer selectCountBySql(String statementCountId) {
        return MybatisDaoImpl.sql(this.tClass).selectCountBySql(statementCountId);
    }

    public Integer updateBySql(String statementId, Map<String, Object> parameterMap) {
        return MybatisDaoImpl.sql(this.tClass).updateBySql(statementId, parameterMap);
    }


}
